package com.cloud.iotdb.utils;

import com.cloud.iotdb.utils.domain.TimeseriesDomain;
import com.cloud.iotdb.utils.wrapper.IotQueryWrapper;
import java.util.List;
import java.util.Map;
import java.util.Set;


public interface IotDBDao {

    /**
     * 根据设备Id创建存储组
     * 创建存储组
     * @param storageGroupName 存储组名称
     * @return 是否成功
     */
    void setStorageGroup(String storageGroupName);


    /**
     * 通过时间序列实体来帮IOTDB建立时间序列
     * 创建时间序列字段
     * @param storageGroup 存储组
     * @param timeseriesDomain 时间序列实体，存储时间序列信息
     * @param deviceId 设备Id 用来标识在存储组
     * @return 是否成功
     */
    void createTimeseries(String storageGroup, TimeseriesDomain timeseriesDomain, Long deviceId);

    /**
     * 单台设备批量保存时间序列
     * @param storageGroup 存储组
     * @param timeseriesDomains 时间序列集合
     * @param deviceId 设备Id
     * @return
     */
    void batchCreateTimeseries(String storageGroup, List<TimeseriesDomain> timeseriesDomains, Long deviceId);



    /**
     * 插入单台设备数据，服务器需要做类型推断
     * @param deviceId 设备Id 用来标识在存储组
     * @param map 单台设备插入
     * @return 是否成功
     */
    void insert(String groupName, Long deviceId, long time, Map<String, Object> map);


    /**
     * 插入单台设备数据，服务器不需要做类型推断
     * @param deviceId 设备Id 用来标识在存储组
     * @param list 每个map中对应，测点：测点值：测点类型
     * @return 是否成功
     */
    void insert(String groupName, Long deviceId, long time, List<TimeseriesDomain> list);

    /**
     * 插入单台设备数据，服务器不需要做类型推断
     * @param deviceId 设备Id 用来标识在存储组
     * @param list 每个map中对应，测点：测点值：测点类型
     * @return 是否成功
     */
    void insert(String groupName, String deviceId, long time, List<TimeseriesDomain> list);

    /**
     * 通一采集时间插入多条设备数据
     * @param groupName 设备组
     * @param deviceIds 设备id列表，与maps对应
     * @param time      采集时间
     * @param maps      采集数据
     */
    void  batchInset(String groupName, List<String> deviceIds, long time, List<Map<String, String>> maps);

    /**
     * 通一采集时间插入多条设备数据
     * @param groupName 设备组
     * @param deviceIds 设备id列表，与maps对应
     * @param time      采集时间
     * @param maps      采集数据
     */
    void  batchInset(String groupName, List<String> deviceIds, long time, List<Map<String, Object>> maps,int index);


    /**
     * 查询设备的最新的一条数据
     * @param groupName 存储组name
     * @param deviceId 设备ID
     * @param params   设备参数set
     * @return 最新的一条数据
     */
    Map<String,Object> getLastData(String groupName, Long deviceId, Set<String> params);

    /**
     * 查询设备的最新的一条数据
     * @param groupName 存储组name
     * @param deviceIds 设备IDs
     * @param params   设备参数set
     * @return 最新的一条数据
     */
    Map<String,Object> getDeviceYield(String groupName, List<Long> deviceIds, Set<String> params);

    /**
     * 获取设备某个字段某一时间段第一条非空数据
     * @param groupName 存储组name
     * @param deviceId 设备ID
     * @param filedName  字段名称
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param isLast    是否是最后一条，否则第一条
     * @return
     */
    Object getFirstOrLastValue(String groupName, Long deviceId, String filedName, long startTime, long endTime, boolean isLast);



    /**
     * 根据设备Id查询设备信息
     *
     * @param deviceId
     * @return List<时间序列Map> key: 时间序列名称  , value:时间序列属性值
     */
//    List<Map<String, Object>> getDataByDeviceId(String deviceId);


    /**
     * 根据设备Id查询该存储组下的时间序列
     *
     * @param deviceId
     * @return List<TimeseriesDomain>
     */
    List<TimeseriesDomain> getTimeseriesByDeviceId(String deviceId);


    /**
     * 查询所有存储组信息
     */
    List<String> showStorageGroup();


    /**
     * 根据wrapper 查询数据， 封装成实体返回(注意不要传last，sql！因为返回的是一个对象不是List)
     * @param wrapper sql封装
     * @param clz    返回类型
     * @return
     */
    <T> List<T> getDataByWrapperList(IotQueryWrapper wrapper, Class<T> clz);

    /**
     * 根据wrapper 查询数据， 封装成实体返回(注意不要传last，sql！因为返回的是一个对象不是List)
     * @param wrapper sql封装
     * @return
     */
    List<Map<String,Object>> getDataByWrapperList(IotQueryWrapper wrapper);


    List<Map<String,Object>> getDataByWrapperList(IotQueryWrapper wrapper, Integer limit);

    List<Map<String,Object>> getDataByWrapperList(IotQueryWrapper wrapper, Integer limit, String desc);

    /**
     * 根据wrapper 查询数据， 封装成实体返回
     * @param wrapper sql封装
     * @param clz    返回类型
     * @return
     */
    <T> T getDataByWrapperOne(IotQueryWrapper wrapper, Class<T> clz);

    /**
     * 根据wrapper 查询数据， 封装成实体返回
     * @param wrapper sql封装
     * @return
     */
    Map<String,Object> getDataByWrapperOne(IotQueryWrapper wrapper);
    /**
     * 根据wrapper 查询数据， 返回一个值（int,String等）
     * @param wrapper sql封装
     * @param clz    返回类型
     * @return
     */
    <T> T getDataByWrapperObject(IotQueryWrapper wrapper, Class<T> clz);


    /**
    * 查询出最后一条数据和最新一条数据的差值
    * */
    Map<String,Object> getDifferentValue(String groupName, Long deviceId, String filedName, long startTime, long endTime);

    /**
     * 按设备对齐查询产量
     * 默认查询所有设备
     * align by device
     * */
    Map<String,Object> getDevicesYield(String groupName, String filedName, List<String> deviceIds, boolean isLast);


//    Map<String,Object> getDevicesYield(String groupName, String filedName, List<Long> deviceIds);

    //查询所有设备的nc程序产量表
//    Map<String,Object> getNcAll(String groupName,String filedName,List<Long> deviceIds,Set<String> params);
}
